#include "RateManagement.h"
#include <wx/log.h>
#include <wx/timer.h>

namespace Impp
{

RateManagement::RateManagement()
{
}

RateManagement::~RateManagement()
{
}


void RateManagement::setRates(std::vector<Rate> & rates, std::vector<RateGroup> & rateGroups){
	this->rates=rates;
	this->rateGroups=rateGroups;
	
}

dword RateManagement::calculateNextLevel(Rate* rate, bool update){
	if(rate==NULL){
		return 0xFFFFFFFF;
	}
	wxLongLong timeSpan = ::wxGetLocalTimeMillis()-rate->timeCurrentLevel;
	dword timeSpanInt = timeSpan.ToLong();
	dword newLevel = rate->currentLevel*(rate->windowSize-1)/rate->windowSize + (timeSpanInt)/rate->windowSize;
	
	newLevel = newLevel < rate->maxLevel ? newLevel : rate->maxLevel;
	
	if(update){
		rate->timeCurrentLevel=::wxGetLocalTimeMillis();
		rate->currentLevel = newLevel;
		
		RateState state = getRateState(rate,newLevel);
		wxLogTrace(wxT("RATE"),wxT("New RateLevel: %i state is now: %i"), newLevel, state);
	}
			
	return newLevel;
}

Rate* RateManagement::getRateByFamilyPair(byte* familyPairData){
	if(!rates.empty() && !rateGroups.empty()){
		Rate* rate = getRate(getFamilyPairDword(familyPairData));
		return rate;
	}
	return NULL;
}

Rate* RateManagement::getRate(dword familyPair){
	
	int rateId = -1;
	
	for(size_t i=0; i < rateGroups.size() && rateId == -1; ++i){
		for(size_t j =0; j < rateGroups[i].familyPairs.size(); ++j){
			if(rateGroups[i].familyPairs[j] == familyPair){
				rateId=rateGroups[i].id;
				break;
			}
		}
	}
	
	if(rateId!=-1){
		Rate* rate = NULL;
		for (size_t i = 0; i < rates.size(); ++i) {
			if(rates[i].id == rateId){
				rate = &rates[i];
				break;
			}
		}
		if(rate!=NULL){
			return rate;
		}else{
			wxLogDebug(wxT("Rate not in rates"));
		}
	}else{
		wxLogDebug(wxT("No Rate id found!"));
	}
	
	return NULL;
}

dword RateManagement::getFamilyPairDword(byte* data){
    dword familyPair(0);
    familyPair |= data[0];
    familyPair <<= 8;
    familyPair |= data[1];
    familyPair <<= 8;
    familyPair |= data[2];
    familyPair <<= 8;
    familyPair |= data[3];
    return familyPair;
}

RateState RateManagement::getRateState(Rate* rate, dword level){
	if(rate==NULL){
		return RATE_CLEAR;
	}
	if(level > rate->clearLevel){
		return RATE_CLEAR;
	}
	if(level > rate->alertLevel){
		return RATE_ALERT;
	}
	if(level > rate->limitLevel){
		return RATE_LIMITED;
	}
	wxLogDebug(wxT("RateManagement::getRateState: Level not in bounds? this should never happen"));
	return RATE_LIMITED;
}

void RateManagement::clearRates(){
	rates.clear();
	rateGroups.clear();
}

}
